home *** CD-ROM | disk | FTP | other *** search
/ Resource Library: Multimedia / Resource Library: Multimedia.iso / maestro / source / dtr / buffer.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-06-15  |  12.3 KB  |  352 lines

  1. /*
  2.  * Copyright (c) 1990, 1991 Stanford University
  3.  *
  4.  * Permission to use, copy, modify, and distribute this software and 
  5.  * its documentation for any purpose is hereby granted without fee, provided
  6.  * that (i) the above copyright notices and this permission notice appear in
  7.  * all copies of the software and related documentation, and (ii) the name
  8.  * Stanford may not be used in any advertising or publicity relating to
  9.  * the software without the specific, prior written permission of
  10.  * Stanford.
  11.  * 
  12.  * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
  13.  * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
  14.  * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
  15.  *
  16.  * IN NO EVENT SHALL STANFORD BE LIABLE FOR ANY SPECIAL, INCIDENTAL,
  17.  * INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES
  18.  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT
  19.  * ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF LIABILITY,
  20.  * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
  21.  * SOFTWARE.
  22.  */
  23.  
  24. /* $Header: /Source/Media/collab/DTR/RCS/buffer.c,v 1.0 92/01/06 17:39:19 drapeau Exp Locker: derek $ */
  25. /* $Log:    buffer.c,v $
  26.  * Revision 1.0  92/01/06  17:39:19  drapeau
  27.  * Collapsed ReadSoundFile() and ReadSoundFileIntoBuffer() into one
  28.  * function, to eliminate redundant code.
  29.  * Also, made a number of cosmetic changes to make code easier to read
  30.  * and to conform to programming specifications.
  31.  * 
  32.  * Revision 0.26  91/09/30  16:12:09  derek
  33.  * DTR will now disconnect from the Port Manager when it quits.  Also,
  34.  * a number of printf statements are removed.
  35.  * 
  36.  * Revision 0.25  91/09/18  22:47:11  derek
  37.  * The following things are done:
  38.  * 1.    The Makefile is changed corresponding to the changes in collab/.
  39.  * 2.    Copyright messages included.
  40.  * 3.    Some minor bugs fixed.
  41.  * 
  42.  * Revision 0.24  91/08/27  18:05:34  derek
  43.  * The SizeToFit bug is fixed.
  44.  * 
  45.  * Revision 0.23  91/08/21  17:46:30  derek
  46.  * The big canvas "mis-placed" bug is fixed.
  47.  * 
  48.  * Revision 0.22  91/08/21  11:34:05  derek
  49.  * The following changes are made:
  50.  * 1.    Now the duration and size of the recorded sound will be displayed
  51.  *     during recording.
  52.  * 2.    I have changed GetSelection() corresponding to the request of Tek joo
  53.  * 3.    Info Panel is added to the application.
  54.  * 4.    Fixed SizeToFitHandler() so that when no file or buffer is currently
  55.  *     loaded, it would not do anything (except giving a warning
  56.  *     notice_prompt).
  57.  * 5.    Inplemented the `Close' Menu option in the document menu.
  58.  * 6.    Fixed the bug in which after ClearAll and I press PreviewEdit,
  59.  *     the edit wont be played.
  60.  * 7.    I have made the changes corresponding to the change in OpenPanel's
  61.  *     name.  (from OpenPanel to Browse).
  62.  * 8.    Incorporated BrowseCheck to check command line arg.
  63.  * 9.    Changed most EditingStatusMessages to NoticePrompts.
  64.  * 10.    SoundFileSaveAsPopUp and EditListSaveAsPopUp are removed 
  65.  *     from the application.
  66.  * 
  67.  * Revision 0.21  91/08/08  21:44:10  derek
  68.  * Fixed a number of bugs.
  69.  * 
  70.  * Revision 0.20  91/08/07  16:23:50  derek
  71.  * The Edit list part of DTR is done.  OpenPanel is also incorporated.
  72.  * 
  73.  * Revision 0.19  91/08/06  12:41:03  derek
  74.  * Edit list panel is done.  Still need to link it to the network code.
  75.  * 
  76.  * Revision 0.18  91/07/30  11:45:14  derek
  77.  * I have fixed the tmp file conflict bug.
  78.  * 
  79.  * Revision 0.17  91/07/26  13:17:40  derek
  80.  * Some saving bugs fixed.
  81.  * 
  82.  * Revision 0.16  91/07/24  12:51:45  derek
  83.  * Disk editing is done.  Now the application can record sound infinitely,
  84.  * as long as there is disk space available.  Command line args are also
  85.  * supported.
  86.  * 
  87.  * Revision 0.15  91/07/23  21:21:23  derek
  88.  * This version is not ready for release.  Disk space editing is half-done:
  89.  * the application can play an infinite sound and the canvases can handle
  90.  * infinite sound files.  The app is pretty bug free too, I think.  The
  91.  * weakness is that it cannot record sound infinitely.  
  92.  * 
  93.  * Revision 0.14  91/06/26  15:54:54  derek
  94.  * I have reformatted the code to conform coding specs.
  95.  * 
  96.  * Revision 0.13  91/06/25  11:37:41  derek
  97.  * I have added the new protocol items.
  98.  * 
  99.  * Revision 0.12  91/06/20  19:55:12  derek
  100.  * The network part should be working.  Also fixed numerous minor parts
  101.  * involving the canvas and the display.
  102.  * 
  103.  * Revision 0.10  1991/04/25  01:44:21  derek
  104.  * This version is checked in on 4/24/91
  105.  * */
  106. static char rcsid[] = "$Header: /Source/Media/collab/DTR/RCS/buffer.c,v 1.0 92/01/06 17:39:19 drapeau Exp Locker: derek $";
  107.  
  108. #include "dtr.h"
  109. #include "dtr_ui.h"
  110.  
  111.  
  112. /* 
  113.  *  Initialize the buffer.
  114.  */
  115. void
  116.   InitBuffer()
  117. {
  118.   EVENT("Init_Buffer");
  119.   
  120.   if (Buffer.data != NULL)
  121.     (void) free((char *)Buffer.data);
  122.   Buffer.data = NULL;
  123.   Buffer.alloc_size = 0;
  124.   Buffer.hdr = Device_phdr;
  125.   Buffer.hdr.data_size = 0;
  126.   SoundBufferReady = FALSE;
  127.   FileReady = FALSE;
  128. }
  129.  
  130.  
  131. /*
  132.  *  Allocate a buffer to hold data.
  133.  */
  134. AllocBuffer(size)
  135.      unsigned    size;
  136. {
  137.   EVENT("Alloc_Buffer");
  138.   
  139.   if (Buffer.data != NULL)
  140.     (void) free((char *)Buffer.data);
  141.   
  142.   do 
  143.   {                                    /*  Allocate a buffer, shrink if request is too...  */
  144.     Buffer.data = (unsigned char *)malloc(size);            /*  ...big.                                         */
  145.   } 
  146.   while ((Buffer.data == NULL) && (size = size - (size / 8)));
  147.   
  148.   Buffer.alloc_size = size;
  149. }
  150.  
  151.  
  152. /*
  153.  *  Set up a new sound buffer and display it.
  154.  */
  155. void
  156.   FileUpdate()
  157. {
  158.   EVENT("File_Update");
  159.   
  160.   Buffer.play.io_position = Buffer.play.start;
  161.   PlayUpdateCursor();
  162. }
  163.  
  164.  
  165. BOOL ReadSoundFile(BOOL intoBuffer)
  166. {
  167.   unsigned                size;
  168.   int                    valid;
  169.   struct stat                st;
  170.   extern BOOL                CanUndo;
  171.   extern dtr_mainWindow_objects*    dtr_mainWindow;
  172.   extern Scrollbar            WaveCanvasScrollbar;
  173.   
  174.   if (intoBuffer == TRUE)
  175.     EVENT("Read_Sound_File_Into_Buffer");
  176.   else
  177.     EVENT("Read_Sound_File");
  178.   if (NullFileName(Buffer.filename) && (SoundBufferReady == TRUE)   /*  Tackle the case when the some sound is...       */
  179.       && NullFileName(currentSoundFile))                /*  ...recorded and it has no name yet, but we...   */
  180.   {                                    /*  ...still want to play it.                       */
  181.     FileReady = FALSE;
  182.     return(TRUE);
  183.   }
  184.   if (strcmp(currentSoundFile, Buffer.filename) == 0)
  185.   {
  186.     if (intoBuffer == FALSE)
  187.     {
  188.       if ((WaveEditMode == FALSE) && (strcmp(currentSoundFile, "Untitled") == 0))
  189.     return(FALSE);
  190.     }
  191.     if (SameSoundFile)
  192.       return(TRUE);
  193.     if (SoundBufferReady == FALSE) 
  194.     {
  195.       if (!NullFileName(Buffer.filename))
  196.       {
  197.     AlertByNoticePrompt(dtr_mainWindow->menuControlPanel,
  198.                 "Error:   File is not valid.");
  199.     return(FALSE);
  200.       }
  201.     }
  202.   }
  203.   else  
  204.   {
  205.     strcpy(Buffer.filename, currentSoundFile);
  206.     SameSoundFile = FALSE;
  207.   }
  208.   if (intoBuffer == FALSE)
  209.   {
  210.     ResetWaveCanvas();
  211.     ResetGlobalWaveCanvas();
  212.   }
  213.   xv_set(WaveCanvasScrollbar, SCROLLBAR_VIEW_START, 0, NULL);        /*  Reset the canvas scrollbar.                     */
  214.   if (xv_get(dtr_mainWindow->zoomSlider, PANEL_VALUE) != 10)        /*  Reset the zoom slider.                          */
  215.     xv_set(dtr_mainWindow->zoomSlider, PANEL_VALUE, 10, NULL);
  216.   Zoom = 1.0;
  217.   
  218.   oldLeftFloatMarker = oldRightFloatMarker = -1.0;            /*  Reset Various Selection parameters.             */
  219.   WaveCanvasRightMarkerSet = FALSE;
  220.   leftButtonHoldPoint = NOTREADY;
  221.   
  222.   oldLeftFloatGbWaveMarker = oldRightFloatGbWaveMarker = -1.0;        /*  Reset Various Selection Parameters for global.. */
  223.   GlobalWaveCanvasRightMarkerSet = FALSE;                /*  ...wave canvas.                                 */
  224.   GbWaveLeftButtonHoldPoint = NOTREADY;
  225.   ClearMessageDisplay();
  226.   if (NullFileName(Buffer.filename))                    /* If there is no file to load, return without doing anything */
  227.     return(FALSE);
  228.   CanUndo = FALSE;                            /*  At this point, there is no way of undo-ing any  */
  229.                                     /*  ...edited wave.                                 */
  230.   if (((soundfd = open(Buffer.filename, O_RDONLY)) < 0) ||        /* Try to open the requested file */
  231.       (fstat(soundfd, &st) < 0))
  232.   {
  233.     sprintf(msg, "Error:   File \"%s\" not found.", 
  234.         Buffer.filename);
  235.     AlertByNoticePrompt(dtr_mainWindow->menuControlPanel, msg);
  236.     strcpy(Buffer.filename, "");
  237.     FileReady = FALSE;
  238.     return (FALSE);
  239.   }
  240.   valid = (AUDIO_SUCCESS==audio_read_filehdr(soundfd,            /*  A soundfile consists of 2 parts: the header...  */
  241.                          &Buffer.hdr,        /*  ...and the data.  We first check whether the... */
  242.                          Buffer.info,        /*  ...soundfile has a header.  If so, read it...   */
  243.                          sizeof(Buffer.info))); /*  ...in and decode it.                            */
  244.   if (valid) 
  245.   {
  246.     if (Buffer.hdr.data_size == AUDIO_UNKNOWN_SIZE)
  247.     {
  248.       Buffer.hdr.data_size =                        /* Calculate the data size, if not already known.   */
  249.     st.st_size - lseek(soundfd, 0L, L_INCR);
  250.     }
  251.   } 
  252.   else                                    /*  If no header, read the file raw and assume...   */
  253.   {                                    /*  ...compatibility.                               */
  254.     Buffer.hdr  = Device_phdr;                        /*  Use device configuration.                       */
  255.     (void) lseek(soundfd, 0L, L_SET);                    /*  Rewind file.                                    */
  256.     Buffer.hdr.data_size = st.st_size - lseek(soundfd, 0L, L_INCR);
  257.     Buffer.info[0] = '\0';
  258.   }
  259.   Buffer.hdr_size = lseek(soundfd, 0L, L_INCR);                /*  Find out the size of the audio header.          */
  260.   if (ActiveFlag & PLAY)                        /*  If active output, set draining flag so that...  */
  261.     Buffer.draining = TRUE;                        /*  ...PlayService() won't try to access the...     */
  262.                                     /*  ...obsolete buffer.  FileUpdate() will turn...  */
  263.                                     /*  ...off the draining flag if output is still...  */
  264.                                     /*  ...active.                                      */
  265.   size = Buffer.hdr.data_size;
  266.   AllocBuffer(size);                            /*  Release the old buffer and allocate a new...    */
  267.                                     /*  ...one to hold the data.                        */
  268.   if (intoBuffer == TRUE)
  269.   {
  270.     Buffer.hdr.data_size = read(soundfd, (char *)Buffer.data,
  271.                 (int)Buffer.alloc_size);        
  272.   }
  273.   (void) close(soundfd);
  274.   Buffer.display.start = Buffer.play.start = 0;
  275.   Buffer.display.end = Buffer.play.end = Buffer.hdr.data_size - 1;
  276.   FileUpdate();
  277.   if (size != Buffer.hdr.data_size) 
  278.   {                                    /*  size = size of soundfile data we expect.        */
  279.     sprintf(msg,                            /*  Buffer.hdr.data_size = the actual amount we...  */
  280.         " %.2f seconds of data truncated from '%s'.",        /*  ...can load.  If we could not allocate or...    */
  281.         audio_bytes_to_secs(&Buffer.hdr,                /*  ...load the file, show msg.                     */
  282.                 (size - Buffer.hdr.data_size)), 
  283.         Buffer.filename);
  284.     AlertByNoticePrompt(dtr_mainWindow->menuControlPanel, msg);
  285.   }
  286.   if (!valid) 
  287.   {
  288.     sprintf(msg, "Error:   '%s' is not a valid audio file",        /*  If file is not an audio file, display a...      */
  289.         Buffer.filename);                        /*  ...warning.                                     */
  290.     AlertByNoticePrompt(dtr_mainWindow->menuControlPanel, msg);
  291.     FileReady = FALSE;
  292.     return(FALSE);
  293.   } else if ((Buffer.hdr.encoding != AUDIO_ENCODING_ULAW) ||
  294.          (Buffer.hdr.bytes_per_unit != 1) ||
  295.          (Buffer.hdr.samples_per_unit != 1) ||
  296.          (Buffer.hdr.channels != 1))
  297.   {
  298.     sprintf(msg, 
  299.         "'%s' audio encoding cannot be played or displayed properly",
  300.         Buffer.filename);
  301.     AlertByNoticePrompt(dtr_mainWindow->menuControlPanel, msg);
  302.   }
  303.   UpdateMessageDisplay();
  304.   Zoom = 1.0;
  305.   UpdateZoomLevelDisplay();
  306.   oldLeftFloatMarker = 0.0;                        /*  Reset markers.                                  */
  307.   oldRightFloatMarker = (double) Buffer.hdr.data_size - 1.0;
  308.   WaveCanvasRightMarkerSet = FALSE;
  309.   oldLeftFloatGbWaveMarker = 0.0;
  310.   oldRightFloatGbWaveMarker = (double) Buffer.hdr.data_size - 1.0;
  311.   GlobalWaveCanvasRightMarkerSet = FALSE;
  312.   if (intoBuffer == TRUE)
  313.   {
  314.     FileReady = FALSE;
  315.     SoundBufferReady = TRUE;
  316.   }
  317.   else
  318.   {
  319.     FileReady = TRUE;
  320.     currentSelectionReadyToPlay = FALSE;
  321.     BufferSaved = TRUE;
  322.   }
  323.   FrameStartingSecond = 0.0;
  324.   return(TRUE);
  325. }                                    /* end function ReadSoundFile */
  326.  
  327.  
  328.  
  329. unsigned char
  330.   GetFileData(pos)
  331. int pos;
  332. {
  333.   static  unsigned char  posData;
  334.   extern      dtr_mainWindow_objects  *dtr_mainWindow;
  335.  
  336.   soundfd = open(Buffer.filename, O_RDONLY);
  337.  
  338.   lseek(soundfd, Buffer.hdr_size + pos, L_SET);
  339.   read(soundfd, &posData, 1);
  340.   close(soundfd);
  341.   
  342.   return(posData);
  343. }
  344.  
  345.  
  346. BOOL
  347.   IsTmpSoundFile(filename)
  348. char  *filename;
  349. {
  350.   return(!strcmp(filename, SoundFileInTmp));
  351. }
  352.